package com.shou.zhnfyxt.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shou.zhnfyxt.Dto.HotSearch;
import com.shou.zhnfyxt.Dto.UserHouseDetail;
import com.shou.zhnfyxt.entity.HouseDetail;
import com.shou.zhnfyxt.entity.R;
import com.shou.zhnfyxt.mapper.HouseDetailMapper;
import com.shou.zhnfyxt.service.HouseDetailService;
import com.shou.zhnfyxt.utils.JwtUtil;
import com.shou.zhnfyxt.utils.RedisCache;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author JCY
 * @since 2022-12-07
 */
@Slf4j
@RestController
@RequestMapping("/houseDetail")
public class HouseDetailController {

    @Autowired
    private HouseDetailMapper houseDetailMapper;
    @Autowired
    private HouseDetailService houseDetailService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedisCache redisCache;


    @GetMapping("getTotalNum")
    public R<Integer> getTotalNum(@RequestParam String houseSearch){
        QueryWrapper<HouseDetail> queryWrapper = new QueryWrapper<>();
        if (houseSearch != null){
            queryWrapper.and(i ->i.like("house_name",houseSearch).or().like("house_third_location",houseSearch));
        }
        String city = "合肥";
        queryWrapper.eq("house_city",city);
        int count = houseDetailService.count(queryWrapper);
        return R.success(count);
    }

    @SuppressWarnings("unchecked")
    @GetMapping("getFirstLocation")
    public R<List<String>> getFirstLocation(@RequestParam String cityTarget){
        ValueOperations valueOperations = redisTemplate.opsForValue();
        List<String> list = new ArrayList<>();
        if (Boolean.TRUE.equals(redisTemplate.hasKey("first_location" + " for " + cityTarget))){
            list = (List<String>) valueOperations.get("first_location" + " for " + cityTarget);
        }else{
            QueryWrapper<HouseDetail> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("house_city",cityTarget);
            List<HouseDetail> houseDetailList = houseDetailService.list(queryWrapper);
            List<String> collect = houseDetailList.stream().map(HouseDetail::getHouseFirstLocation).collect(Collectors.toList());
            list = collect.stream().distinct().collect(Collectors.toList());
            valueOperations.set("first_location" + " for " + cityTarget,list);
            redisTemplate.expire("first_location" + " for " + cityTarget,3, TimeUnit.HOURS);
        }
        return R.success(list);
    }


    @SuppressWarnings("unchecked")
    @PostMapping("getAllHouseDetail")
    public R< Map<String, Object>> getAllHouseDetail(@RequestBody Map<String, Object> params, @RequestHeader String token){
        Map<String, Object> map  = (Map<String, Object>) params.get("data");
        String sortController = (String) map.get("sortController");
        Integer pageSize = (Integer) map.get("pageSize");
        Integer currentPage = (Integer) map.get("currentPage");
        String houseSearch = (String) map.get("houseSearch");
        String cityTarget = (String) map.get("cityTarget");
        Claims claims = JwtUtil.parseJWT(token);
        String userId = claims.getSubject();

        //分页
        Page<HouseDetail> houseDetailPage = new Page<>(currentPage, pageSize);
        QueryWrapper<HouseDetail> queryWrapper = new QueryWrapper<>();

        //处理排序
        if (Objects.equals(sortController, "totalPriceAsc")){
            queryWrapper.orderByAsc("house_total_price");
        }else if (Objects.equals(sortController, "totalPriceDesc")){
            queryWrapper.orderByDesc("house_total_price");
        }else if (Objects.equals(sortController, "averagePriceAsc")){
            queryWrapper.orderByAsc("house_average_price");
        }else if (Objects.equals(sortController, "averagePriceDesc")){
            queryWrapper.orderByDesc("house_average_price");
        }


        Map<String, Object> classify = (Map<String, Object>) map.get("classify");

        //处理选中的面积
        List<Integer> checkedArea = (List<Integer>) classify.get("checkedArea");
        checkedArea.forEach(area -> {
            System.out.println(area);
            if (checkedArea.size() == 1) {
                List<Integer> areaNumber = houseDetailService.getAreaNumber(area);
                if (area == 1) {
                    queryWrapper.and(i -> i.between("house_area", areaNumber.get(0), areaNumber.get(1)));
                } else if (area == 2) {
                    queryWrapper.and(i -> i.between("house_area", areaNumber.get(0), areaNumber.get(1)));
                } else if (area == 3) {
                    queryWrapper.and(i -> i.between("house_area", areaNumber.get(0), areaNumber.get(1)));
                } else if (area == 4) {
                    queryWrapper.and(i -> i.between("house_area", areaNumber.get(0), areaNumber.get(1)));
                } else if (area == 5) {
                    queryWrapper.and(i -> i.between("house_area", areaNumber.get(0), areaNumber.get(1)));
                } else if (area == 6) {
                    queryWrapper.and(i -> i.between("house_area", areaNumber.get(0), areaNumber.get(1)));
                } else if (area == 7) {
                    queryWrapper.and(i -> i.between("house_area", areaNumber.get(0), areaNumber.get(1)));
                }
            }
        });

        List<Integer> checkedPrice = (List<Integer>) classify.get("checkedPrice");
        checkedPrice.forEach(price -> {
            if (price == 1){
                queryWrapper.and(i -> i.between("house_total_price",0,100));
            }
            if (price == 2){
                queryWrapper.and(i -> i.between("house_total_price",100,200));
            }if (price == 3){
                queryWrapper.and(i -> i.between("house_total_price",200,400));
            }if (price == 4){
                queryWrapper.and(i -> i.between("house_total_price",400,800));
            }if (price == 5){
                queryWrapper.and(i -> i.between("house_total_price",800,999999));
            }
        });


        //处理选中的区县
        List<String> checkedLocation = (List<String>) classify.get("checkedLocation");
        if (!checkedLocation.isEmpty()) {
            queryWrapper.in("house_first_location", checkedLocation);
        }

//        处理搜索框
        if (houseSearch != null){
            queryWrapper.and(i ->i.like("house_name",houseSearch).or().like("house_third_location",houseSearch));
            //处理热点数据
            if (Boolean.TRUE.equals(redisTemplate.hasKey("recentHotSearch"))){
                Map<String, Object> recentHotSearch = redisCache.getCacheObject("recentHotSearch");
                if (!houseSearch.equals("")){
                    assert recentHotSearch != null;
                    if (recentHotSearch.containsKey(houseSearch)){
                        Integer count = (Integer) recentHotSearch.get(houseSearch);
                        count++;
                        recentHotSearch.put(houseSearch,count);
                        redisTemplate.opsForValue().set("recentHotSearch",recentHotSearch);
                    }else {
                        recentHotSearch.put(houseSearch,1);
                        redisTemplate.opsForValue().set("recentHotSearch",recentHotSearch);
                    }
                }


            }else {
                Map<String, Integer> hashMap = new HashMap<>();
                hashMap.put(houseSearch, 1);
                redisTemplate.opsForValue().set("recentHotSearch",hashMap);
            }
        }

        queryWrapper.and(i->i.eq("house_city",cityTarget));


        Page<HouseDetail> houseDetails = houseDetailMapper.selectPage(houseDetailPage, queryWrapper);
        List<HouseDetail> records = houseDetails.getRecords();
        ArrayList<UserHouseDetail> userHouseDetails = new ArrayList<>();
        for (HouseDetail detail : records) {
            UserHouseDetail userHouseDetail = new UserHouseDetail();
            userHouseDetail.setHouseId(detail.getHouseId());
            userHouseDetail.setHouseName(detail.getHouseName());
            userHouseDetail.setHouseFirstLocation(detail.getHouseFirstLocation());
            userHouseDetail.setHouseSecondLocation(detail.getHouseSecondLocation());
            userHouseDetail.setHouseThirdLocation(detail.getHouseThirdLocation());
            userHouseDetail.setHouseType(detail.getHouseType());
            userHouseDetail.setHouseHref(detail.getHouseHref());
            userHouseDetail.setHouseCity(detail.getHouseCity());
            userHouseDetail.setHouseArea(detail.getHouseArea());
            userHouseDetail.setHouseAveragePrice(detail.getHouseAveragePrice());
            userHouseDetail.setHouseTotalPrice(detail.getHouseTotalPrice());
            userHouseDetails.add(userHouseDetail);
        }


        List<Integer> favourites = redisCache.getCacheList("favourite:" + userId);
        log.info(favourites.toString());
        for (UserHouseDetail userHouseDetail : userHouseDetails){
            for (Integer favourite : favourites){
                if (Objects.equals(userHouseDetail.getHouseId(), favourite)){
                    userHouseDetail.setFavorites(1);
                }
            }
        }

        Integer selectCount = houseDetailMapper.selectCount(queryWrapper);
        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("selectCount", selectCount);
        returnMap.put("houseDetails", userHouseDetails);
        return R.success(returnMap);
    }


    @SuppressWarnings("unchecked")
    @GetMapping("getAllCity")
    public R<List<String>> getAllCity(){
        ValueOperations valueOperations = redisTemplate.opsForValue();
        List<String> city = new ArrayList<>();
        if(Boolean.TRUE.equals(redisTemplate.hasKey("cityList"))){
            city = (List<String>) valueOperations.get("cityList");
        }else{
            List<HouseDetail> list = houseDetailService.list();
            List<String> collect = list.stream().map(HouseDetail::getHouseCity).collect(Collectors.toList());
            city= collect.stream().distinct().collect(Collectors.toList());
            valueOperations.set("cityList",city);
            redisTemplate.expire("cityList",3,TimeUnit.HOURS);
        }

        return R.success(city);
    }

    @GetMapping("getHotSearch")
    public R<List<HotSearch>> getHotSearch(){
        Map<String,Integer> map = (Map<String, Integer>) redisTemplate.opsForValue().get("recentHotSearch");
        Map<String, Integer> newMap = new LinkedHashMap<>();
        assert map != null;
        map.entrySet().stream().sorted((o1, o2) ->o2.getValue() - o1.getValue()).forEach(e -> newMap.put(e.getKey(), e.getValue()));
        System.out.println(newMap);
        List<HotSearch> list = new ArrayList<>();
        int index = 0;
        for (String s : newMap.keySet()) {
            if (index <= 10){
                HotSearch hotSearch = new HotSearch();
                hotSearch.setValue(s);
                list.add(hotSearch);
                index ++;
            }
        }
        return R.success(list);

    }

    @PostMapping("insertUserFavorite")
    public R<Boolean> insertUserFavorite(@RequestBody Integer houseId, @RequestHeader String token){
        System.out.println(houseId);
        ArrayList<Integer> list = new ArrayList<>();
        list.add(houseId);
        Claims claims = JwtUtil.parseJWT(token);
        String userId = claims.getSubject();
        redisCache.setCacheList("favourite:" + userId, list);
        return R.success(true);
    }

    @PostMapping("deleteUserFavorite")
    public R<Boolean> deleteUserFavorite(@RequestBody Integer houseId, @RequestHeader String token){
        Claims claims = JwtUtil.parseJWT(token);
        String userId = claims.getSubject();
        redisTemplate.opsForList().remove("favourite:" + userId,0, houseId);
        return R.success(true);
    }

    @GetMapping ("getUserFavorite")
    public R<List<HouseDetail>> getUserFavorite(@RequestHeader String token){
        Claims claims = JwtUtil.parseJWT(token);
        String userId = claims.getSubject();
        List<Integer> favourites  = redisTemplate.opsForList().range("favourite:" + userId,0,-1);
        System.out.println(favourites);
        ArrayList<HouseDetail> houseDetails = new ArrayList<>();
        for (Integer favourite : favourites){
            QueryWrapper<HouseDetail> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("house_id",favourite);
            HouseDetail houseDetail = houseDetailMapper.selectOne(queryWrapper);
            houseDetails.add(houseDetail);
        }
        System.out.println(houseDetails);
        return R.success(houseDetails);
    }
    @GetMapping("upload")
    public R<String> upload(){
        return R.success("upload");
    }
}

